﻿using System;
using System.Threading;
using System.Windows.Input;
using System.Windows.Navigation;
using BabyCloudDrives.DesktopApp.Utilities;
using BabyCloudDrives.DesktopApp.ViewModels.Base;

namespace BabyCloudDrives.DesktopApp.ViewModels
{
    public class OAuthViewModel : ObservableObject
    {
        private const string Scope = "wl.signin%20wl.basic%20wl.skydrive%20wl.skydrive_update";
        private Uri _oAuthUrl;
        private bool _isLoaded;
        private string _loadingMessage;
        private bool _isLoading;

        public Uri OAuthUri
        {
            get
            {
                IsLoading = true;
                ShowLoadingMessage("loading now,please waiting", () => IsLoading);
                return _oAuthUrl;
            }
            set { _oAuthUrl = value; }
        }

        public ICommand OnLoadCompleted { get; set; }

        public bool IsLoaded
        {
            get { return _isLoaded; }
            set
            {
                _isLoaded = value;
                OnPropertyChanged("IsLoaded");
            }
        }

        public string LoadingMessage
        {
            get { return _loadingMessage; }
            set
            {
                _loadingMessage = value;
                OnPropertyChanged("LoadingMessage");
            }
        }

        public bool IsLoading
        {
            get { return _isLoading; }
            set
            {
                _isLoading = value;
                OnPropertyChanged("IsLoading");
            }
        }

        public bool UnLogin
        {
            get { return string.IsNullOrEmpty(PresetValues.ResponseValue.AccessToken); }
        }

        public OAuthViewModel()
        {
            //https://oauth.live.com/desktop
            const string redirectUrl = "https://login.live.com/oauth20_desktop.srf";
            const string refreshTokenParamStr = "&grant_type=refresh_token";
            //https://oauth.live.com/authorize
            OAuthUri = new Uri(string.Format(
                "https://login.live.com/oauth20_authorize.srf?client_id={0}&display=touch&redirect_uri={1}&response_type=token&scope={2}" +
                refreshTokenParamStr,
                PresetValues.ClientId, redirectUrl, Scope));
            OnLoadCompleted = new ActionCommand(LoadCompleted);
        }

        private void LoadCompleted(object eventArgs)
        {
            var navigationEventArgs = eventArgs as NavigationEventArgs;
            if (navigationEventArgs == null) return;
            if (navigationEventArgs.Uri != null && !string.IsNullOrEmpty(navigationEventArgs.Uri.Fragment)
                && navigationEventArgs.Uri.Fragment.Contains(PresetValues.ResponseKey.AccessToken))
            {
                string fragment = navigationEventArgs.Uri.Fragment;
                string[] responseAll = fragment.Remove(0, 1).Split(new[] {'&'}, StringSplitOptions.RemoveEmptyEntries);
                PresetValues.AllResponses.Clear();
                foreach (string keyValue in responseAll)
                {
                    string[] keyValues = keyValue.Split(new[] {'='}, StringSplitOptions.RemoveEmptyEntries);
                    if (keyValues.Length < 2) continue;

                    if (keyValues[0] == PresetValues.ResponseKey.AccessToken ||
                        keyValues[0] == PresetValues.ResponseKey.RefreshToken)
                        PresetValues.ResponseValue.AccessToken = keyValues[1];
                    else
                        PresetValues.AllResponses.Add(keyValues[0], keyValues[1]);
                }
                IsLoaded = true;
            }
            else if (navigationEventArgs.Uri != null && (string.IsNullOrEmpty(navigationEventArgs.Uri.Fragment) ||
                                                         navigationEventArgs.Uri.Fragment.Contains(
                                                             PresetValues.ResponseKey.Error)))
            {
                IsLoading = false;
            }
        }

        private void ShowLoadingMessage(string currentMessage, Func<bool> canBeInvokeFun)
        {
            new Action(() =>
                {
                    string dotStr = ".";
                    LoadingMessage = currentMessage;
                    while (canBeInvokeFun())
                    {
                        dotStr += ".";
                        if (dotStr.Length > 6) dotStr = ".";
                        LoadingMessage = currentMessage + dotStr;
                        Thread.Sleep(300);
                    }
                }).BeginInvoke(null, null);
        }
    }
}